package com.adinall.dsp.core.db;

import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * DB Help
 * 
 * @author 高万超
 * @version V1.0.0 $ 2017年6月20日 下午7:19:16
 */
public final class DBHelper {

    public static <T> List<T> mapping(ResultSet rs, Class<T> clazz) throws Exception {

        if (rs == null) {
            return null;
        }

        List<T> result = new ArrayList<T>();

        try {

            int columnCount = rs.getMetaData().getColumnCount();

            while (rs.next()) {

                T t = (T) Class.forName(clazz.getName()).newInstance();

                for (int i = 1; i <= columnCount; i++) {

                    String columnLable = rs.getMetaData().getColumnLabel(i);
                    columnLable = columnLable.substring(0, 1).toUpperCase() + columnLable.substring(1, columnLable.length());

                    Method readMethod = t.getClass().getDeclaredMethod("get" + columnLable);
                    Method writeMethod = t.getClass().getDeclaredMethod("set" + columnLable, readMethod.getReturnType());
                    writeMethod.invoke(t, getValueByType(rs, readMethod.getReturnType().getName(), columnLable));
                }

                result.add(t);
            }
        } catch (SQLException e) {
            throw e;
        }

        return result;
    }

    public static List<Map<String, Object>> mapping(ResultSet rs) throws Exception {

        if (rs == null) {
            return null;
        }

        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();

        try {

            int columnCount = rs.getMetaData().getColumnCount();

            Map<String, Object> map;

            while (rs.next()) {

                map = new LinkedHashMap<>();

                for (int i = 1; i <= columnCount; i++) {
                    map.put(rs.getMetaData().getColumnLabel(i), rs.getObject(i));
                }

                result.add(map);
            }
        } catch (SQLException e) {
            throw e;
        }

        return result;
    }

    private static Object getValueByType(ResultSet rs, String s, String s1) throws Exception {

        Class[] clazz = { String.class };
        String type = TypeMappings.java2ResultsetGetter.get(s);

        if (type == null) {
            return null;
        }

        try {
            Method method = ResultSet.class.getDeclaredMethod(type, clazz);
            return method.invoke(rs, s1);
        } catch (Exception e) {
            System.out.println(e + ":" + s1);
            throw e;
        }
    }
}